home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / main / ds5000.md / mainInit.c < prev    next >
C/C++ Source or Header  |  1991-06-27  |  13KB  |  520 lines

  1. /* 
  2.  *  main.c --
  3.  *
  4.  *    The main program for Sprite: initializes modules and creates
  5.  *    system processes. Also creates a process to run the Init program.
  6.  *
  7.  * Copyright 1984 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /sprite/src/kernel/main/ds5000.md/RCS/mainInit.c,v 1.4 91/06/27 12:13:59 shirriff Exp $ SPRITE (DECWRL)";
  19. #endif /* !lint */
  20.  
  21. #include <sprite.h>
  22. #include <dbg.h>
  23. #include <dev.h>
  24. #include <net.h>
  25. #include <proc.h>
  26. #include <prof.h>
  27. #include <fsutil.h>
  28. #include <recov.h>
  29. #include <rpc.h>
  30. #include <sched.h>
  31. #include <sig.h>
  32. #include <sync.h>
  33. #include <sys.h>
  34. #include <timer.h>
  35. #include <vm.h>
  36. #include <machMon.h>
  37. #include <mach.h>
  38. #include <fs.h>
  39. #include <main.h>
  40. #include <stdio.h>
  41.  
  42. static void Init _ARGS_((void));
  43.  
  44. /*
  45.  *  Pathname of the Init program.
  46.  */
  47. #define INIT         "cmds/initsprite"
  48.  
  49. int main_PrintInitRoutines = FALSE;/* print out each routine as it's called? */
  50. int main_PanicOK = 0;    /* Set to 1 if it's OK to panic. */
  51.  
  52. /*
  53.  *----------------------------------------------------------------------
  54.  *
  55.  * main --
  56.  *
  57.  *    All kernel modules are initialized by calling their *_Init()
  58.  *    routines. In addition, kernel processes are created to
  59.  *    handle virtual memory and rpc-specific stuff. The last process
  60.  *    created runs the `init' program.
  61.  *
  62.  * Results:
  63.  *    None.
  64.  *
  65.  * Side effects:
  66.  *    The whole system is initialized.
  67.  *
  68.  *----------------------------------------------------------------------
  69.  */
  70.  
  71. void
  72. main(argc,argv)
  73. int argc;
  74. MachStringTable *argv;
  75. {
  76.     Proc_PID    pid;
  77.     int        i;
  78.     int        numArgs;
  79.     char    argBuffer[256];
  80.     char    *args[10];
  81.  
  82.     /*
  83.      * Initialize variables specific to a given kernel.  
  84.      * IMPORTANT: Only variable assignments and nothing else can be
  85.      *          done in this routine.
  86.      */
  87.     Main_InitVars();
  88.  
  89.     /*
  90.      * Initialize machine dependent info.  MUST BE CALLED HERE!!!.
  91.      */
  92.     if (main_PrintInitRoutines) {
  93.     Mach_MonPrintf("Calling Mach_Init().\n");
  94.     }
  95.     Mach_Init(argc, argv);
  96.     numArgs = Mach_GetBootArgs(10, 256, args, argBuffer);
  97.     for (i = 0; i < numArgs; i++) {
  98.     if (!strcmp(args[i], "-v")) {
  99.         main_PrintInitRoutines = TRUE;
  100.         break;
  101.     }
  102.     }
  103.     if (main_PrintInitRoutines) {
  104.     Mach_MonPrintf("Calling Sync_Init().\n");
  105.     }
  106.  
  107.     /*
  108.      * Initialize variables again, since Mach_Init trashes them.
  109.      */
  110.     Main_InitVars();
  111.  
  112.     Sync_Init();
  113.  
  114.     /*
  115.      * Initialize the debugger.
  116.      */
  117.     if (main_PrintInitRoutines) {
  118.     Mach_MonPrintf("Calling Dbg_Init().\n");
  119.     }
  120.     Dbg_Init();
  121.  
  122.     /*
  123.      * Initialize the system module, particularly the fact that there is an
  124.      * implicit DISABLE_INTR on every processor.
  125.      */
  126.     if (main_PrintInitRoutines) {
  127.     Mach_MonPrintf("Calling Sys_Init().\n");
  128.     }
  129.     Sys_Init();
  130.  
  131.     /*
  132.      * Now allow memory to be allocated by the "Vm_BootAlloc" call.  Memory
  133.      * can be allocated by this method until "Vm_Init" is called.  After this
  134.      * then the normal memory allocator must be used.
  135.      */
  136.     if (main_PrintInitRoutines) {
  137.     Mach_MonPrintf("Calling Vm_BootInit().\n");
  138.     }
  139.     Vm_BootInit();
  140.  
  141.     /*
  142.      * Initialize all devices.
  143.      */
  144.     if (main_PrintInitRoutines) {
  145.     Mach_MonPrintf("Calling Dev_Init().\n");
  146.     }
  147.     Dev_Init();
  148.  
  149.     /*
  150.      *  Initialize the mappings of keys to call dump routines.
  151.      *  Must be after Dev_Init. 
  152.      */
  153.     if (main_DoDumpInit) {
  154.     if (main_PrintInitRoutines) {
  155.         Mach_MonPrintf("Calling Dump_Init().\n");
  156.     }
  157.     Dump_Init();
  158.     }
  159.  
  160.     /*
  161.      * Initialize the timer, signal, process, scheduling and synchronization
  162.      * modules' data structures.
  163.      */
  164.     if (main_PrintInitRoutines) {
  165.     Mach_MonPrintf("Calling Proc_Init().\n");
  166.     }
  167.     Proc_Init();
  168.     if (main_PrintInitRoutines) {
  169.     Mach_MonPrintf("Calling Sync_LockStatInit().\n");
  170.     }
  171.     Sync_LockStatInit();
  172.     if (main_PrintInitRoutines) {
  173.     Mach_MonPrintf("Calling Timer_Init().\n");
  174.     }
  175.     Timer_Init();
  176.     if (main_PrintInitRoutines) {
  177.     Mach_MonPrintf("Calling Sig_Init().\n");
  178.     }
  179.     Sig_Init();
  180.     if (main_PrintInitRoutines) {
  181.     Mach_MonPrintf("Calling Sched_Init().\n");
  182.     }
  183.     Sched_Init();
  184.  
  185.     /*
  186.      * Sys_Printfs are not allowed before this point.
  187.      */  
  188.     main_PanicOK++;
  189.     printf("Sprite kernel: %s\n", SpriteVersion());
  190.  
  191.     /*
  192.      * Set up bins for the memory allocator.
  193.      */
  194.     if (main_PrintInitRoutines) {
  195.     Mach_MonPrintf("Calling Fs_Bin\n");
  196.     }
  197.     Fs_Bin();
  198.     if (main_PrintInitRoutines) {
  199.     Mach_MonPrintf("Calling Net_Bin\n");
  200.     }
  201.     Net_Bin();
  202.  
  203.     /*
  204.      * Initialize virtual memory.  After this point must use the normal
  205.      * memory allocator to allocate memory.  If you use Vm_BootAlloc then
  206.      * will get a panic into the debugger.
  207.      */
  208.     if (main_PrintInitRoutines) {
  209.     Mach_MonPrintf("Calling Vm_Init\n");
  210.     }
  211.     Vm_Init();
  212.  
  213.     /*
  214.      * malloc can be called from this point on.
  215.      */
  216.  
  217.     /*
  218.      * Initialize the main process. Must be called before any new 
  219.      * processes are created.
  220.      * Dependencies: Proc_InitTable, Sched_Init, Vm_Init, Mem_Init
  221.      */
  222.     if (main_PrintInitRoutines) {
  223.     Mach_MonPrintf("Calling Proc_InitMainProc\n");
  224.     }
  225.     Proc_InitMainProc();
  226.  
  227.     if (main_PrintInitRoutines) {
  228.     Mach_MonPrintf("Calling Net_Init\n");
  229.     }
  230.     Net_Init();
  231.     /*
  232.      * Initialize the routes.
  233.      */
  234.     if (main_PrintInitRoutines) {
  235.     Mach_MonPrintf("Calling Net_RouteInit\n");
  236.     }
  237.     Net_RouteInit();
  238.  
  239.  
  240.     /*
  241.      * Enable server process manager.
  242.      */
  243.     if (main_PrintInitRoutines) {
  244.     Mach_MonPrintf("Calling Proc_ServerInit\n");
  245.     }
  246.     Proc_ServerInit();
  247.  
  248.     /*
  249.      * Initialize the recovery module.  Do before Rpc and after Vm_Init.
  250.      */
  251.     if (main_PrintInitRoutines) {
  252.     Mach_MonPrintf("Calling Recov_Init\n");
  253.     }
  254.     Recov_Init();
  255.  
  256.     /*
  257.      * Initialize the data structures for the Rpc system.  This uses
  258.      * Vm_RawAlloc to so it must be called after Vm_Init.
  259.      * Dependencies: Timer_Init, Vm_Init, Net_Init, Recov_Init
  260.      */
  261.     if (main_PrintInitRoutines) {
  262.     Mach_MonPrintf("Calling Rpc_Init\n");
  263.     }
  264.     Rpc_Init();
  265.  
  266.     /*
  267.      * Configure devices that may or may not exist.  This needs to be
  268.      * done after Proc_InitMainProc because the initialization routines
  269.      * use SetJump which uses the proc table entry for the main process.
  270.      */
  271.     if (main_PrintInitRoutines) {
  272.     Mach_MonPrintf("Calling Dev_Config\n");
  273.     }
  274.     Dev_Config();
  275.  
  276.     /*
  277.      * Initialize profiling after the timer and vm stuff is set up.
  278.      * Dependencies: Timer_Init, Vm_Init
  279.      */
  280.     if (main_DoProf) {
  281.     Prof_Init();
  282.     }
  283.     /*
  284.      *  Allow interrupts from now on.
  285.      */
  286.     if (main_PrintInitRoutines) {
  287.     Mach_MonPrintf("Enabling interrupts\n");
  288.     }
  289.     ENABLE_INTR();
  290.     if (main_Debug) {
  291.     DBG_CALL;
  292.     }
  293.  
  294.     /*
  295.      * Sleep for a few seconds to calibrate the idle time ticks.
  296.      */
  297.     Sched_TimeTicks();
  298.  
  299.     /*
  300.      * Start profiling, if desired.
  301.      */
  302.     if (main_DoProf) {
  303.         (void) Prof_Start();
  304.     }
  305.  
  306.     /*
  307.      * Do an initial RPC to get a boot timestamp.  This allows
  308.      * servers to detect when we crash and reboot.  This will set the
  309.      * system clock too, although rdate is usually done from user level later.
  310.      */
  311.     if (main_PrintInitRoutines) {
  312.     printf("Call Rpc_Start\n");
  313.     }
  314.     Rpc_Start();
  315.  
  316.     /*
  317.      * Initialize the file system. 
  318.      */
  319.     if (main_PrintInitRoutines) {
  320.     printf("Call Fs_Init\n");
  321.     }
  322.     Fs_Init();
  323.  
  324.     /*
  325.      * Before starting up any more processes get a current directory
  326.      * for the main process.  Subsequent new procs will inherit it.
  327.      */
  328.     if (main_PrintInitRoutines) {
  329.     printf("Call Fs_ProcInit\n");
  330.     }
  331.     Fs_ProcInit();
  332.  
  333. #ifdef TESTING
  334.     device.unit = 0;
  335.     Dev_ConsoleOpen(&device, FS_READ, NIL);
  336.     while (1) {
  337.     char        buf[11];
  338.     int        len;
  339.     Time        time;
  340.  
  341.     time.seconds = 1;
  342.     time.microseconds = 0;
  343.  
  344.     if (Dev_ConsoleRead(&device, 0, 10, buf, &len) == SUCCESS) {
  345.         printf("%s", buf);
  346.     }
  347.     Sync_WaitTime(time);
  348.     }
  349. #endif
  350.  
  351.     if (main_PrintInitRoutines) {
  352.     printf("Bunch of call funcs\n");
  353.     }
  354.     /*
  355.      * Start the clock daemon and the routine that opens up the swap directory.
  356.      */
  357.     Proc_CallFunc(Vm_Clock, (ClientData) NIL, 0);
  358.     Proc_CallFunc(Vm_OpenSwapDirectory, (ClientData) NIL, 0);
  359.  
  360.     /*
  361.      * Start the process that synchronizes the filesystem caches
  362.      * with the data kept on disk.
  363.      */
  364.     Proc_CallFunc(Fsutil_SyncProc, (ClientData) NIL, 0);
  365.  
  366.     /*
  367.      * Create a few RPC server processes and the Rpc_Daemon process which
  368.      * will create more server processes if needed.
  369.      */
  370.     if (main_NumRpcServers > 0) {
  371.     for (i=0 ; i<main_NumRpcServers ; i++) {
  372.         (void) Rpc_CreateServer((int *) &pid);
  373.     }
  374.     }
  375.     (void) Proc_NewProc((Address)(unsigned)(int (*)())Rpc_Daemon, 
  376.             PROC_KERNEL, FALSE, &pid, "Rpc_Daemon");
  377.     if (main_PrintInitRoutines) {
  378.     printf("Creating Proc server procs\n");
  379.     }
  380.  
  381.     /*
  382.      * Create processes  to execute functions.
  383.      */
  384.     for (i = 0; i < proc_NumServers; i++) {
  385.     (void) Proc_NewProc((Address)(unsigned)(int (*)()) Proc_ServerProc,
  386.                 PROC_KERNEL, FALSE,    &pid, "Proc_ServerProc");
  387.     }
  388.  
  389.     /*
  390.      * Create a recovery process to monitor other hosts.  Can't use
  391.      * Proc_CallFunc's to do this because they can be used up waiting
  392.      * for page faults against down servers.  (Alternatively the VM
  393.      * code could be fixed up to retry page faults later instead of
  394.      * letting the Proc_ServerProc wait for recovery.)
  395.      */
  396.     (void) Proc_NewProc((Address) Recov_Proc, PROC_KERNEL, FALSE, &pid,
  397.             "Recov_Proc");
  398.  
  399.     /*
  400.      * Set up process migration recovery management.
  401.      */
  402.     if (main_PrintInitRoutines) {
  403.     printf("Calling Proc_MigInit\n");
  404.     }
  405.     Proc_MigInit();
  406.  
  407.     /*
  408.      * Call the routine to start test kernel processes.
  409.      */
  410.  
  411.     if (main_PrintInitRoutines) {
  412.     printf("Calling Main_HookRoutine\n");
  413.     }
  414.     Main_HookRoutine();
  415.  
  416.     /*
  417.      * Print out the amount of memory used.
  418.      */
  419.     printf("MEMORY %d bytes allocated for kernel\n", 
  420.         vmMemEnd - mach_KernStart);
  421.  
  422.     /*
  423.      * Start up the first user process.
  424.      */
  425.     if (main_PrintInitRoutines) {
  426.     printf("Creating Init\n");
  427.     }
  428.     (void) Proc_NewProc((Address)(unsigned)(int (*)())Init, PROC_KERNEL,
  429.             FALSE, &pid, "Init");
  430.  
  431.     (void) Sync_WaitTime(time_OneYear);
  432.     printf("Main exiting\n");
  433.     Proc_Exit(0);
  434. }
  435.  
  436.  
  437. /*
  438.  *----------------------------------------------------------------------
  439.  *
  440.  * Init --
  441.  *
  442.  *    This routine execs the init program.
  443.  *
  444.  * Results:
  445.  *    This routine only returns an error if the exec failed.
  446.  *
  447.  * Side effects:
  448.  *    The current process image is overlayed by the init process.
  449.  *
  450.  *----------------------------------------------------------------------
  451.  */
  452. static void
  453. Init()
  454. {
  455.     char        *initArgs[10];
  456.     ReturnStatus    status;
  457.     char        argBuffer[256];
  458.     int            argc;
  459.     Fs_Stream        *dummy;
  460.     char        bootCommand[103];
  461.     char        *ptr;
  462.     int            i;
  463.     int            argLength;
  464.  
  465.     if (main_PrintInitRoutines) {
  466.     Mach_MonPrintf("In Init\n");
  467.     }
  468.     bzero(bootCommand, 103);
  469.     argc = Mach_GetBootArgs(8, 256, &(initArgs[1]), argBuffer);
  470.     if (argc>0) {
  471.     argLength = (((int) initArgs[argc]) + strlen(initArgs[argc]) +
  472.             1 - ((int) argBuffer));
  473.     } else {
  474.     argLength = 0;
  475.     }
  476.     if (argLength > 0) {
  477.     initArgs[1] = "-b";
  478.     ptr = bootCommand;
  479.     for (i = 0; i < argLength; i++) {
  480.         if (argBuffer[i] == '\0') {
  481.         *ptr++ = ' ';
  482.         } else {
  483.         *ptr++ = argBuffer[i];
  484.         }
  485.     }
  486.     bootCommand[argLength] = '\0';
  487.     initArgs[2] = bootCommand;
  488.     initArgs[(argc-1) + 2] = (char *) NIL;
  489.     } else {
  490.     initArgs[1] = (char *) NIL;
  491.     }
  492.     if (main_AltInit != 0) {
  493.     initArgs[0] = main_AltInit;
  494.     printf("Execing \"%s\"\n", initArgs[0]);
  495.     status = Proc_KernExec(initArgs[0], initArgs);
  496.     printf( "Init: Could not exec %s status %x.\n",
  497.             initArgs[0], status);
  498.     }
  499.     status = Fs_Open(INIT,FS_EXECUTE | FS_FOLLOW, FS_FILE, 0, &dummy);
  500.     if (status != SUCCESS) {
  501.     printf("Can't open %s <0x%x>\n", INIT,status);
  502.     }
  503.     initArgs[0] = INIT;
  504.     status = Proc_KernExec(initArgs[0], initArgs);
  505.     printf( "Init: Could not exec %s status %x.\n",
  506.             initArgs[0], status);
  507.     Proc_Exit(1);
  508. }
  509.  
  510. TestEther()
  511. {
  512.     extern Boolean    dbg_UsingNetwork;
  513.  
  514.     dbg_UsingNetwork = TRUE;
  515.  
  516.     while (1) {
  517.     Net_RecvPoll();
  518.     }
  519. }
  520.